package com.sokobanboxpro.game.managers;

import com.sokobanboxpro.game.gameplay.Level;
import com.sokobanboxpro.game.system.Config;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

/**
 * Менеджер уровней.
 *
 * @author Esr
 */
public class LevelManager {

		/**
		 * Массив существующий уровней.
		 */
		private static Level[] levels = null;

		/**
		 * Загрузить уровени из файла.
		 *
		 * @param path Путь до файла
		 * @throws Exception
		 */
		public static void loadLevelFromFile(String path) throws Exception {

				BufferedReader reader;
				InputStream inStream = Config.class.getResourceAsStream(path);
				reader = new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1"));

				ArrayList<Integer> readedFileBytes = new ArrayList<Integer>();

				int nextByte;

				while ((nextByte = reader.read()) != -1) {

						if (nextByte < 0) {
								nextByte = nextByte & 255;
						}
						readedFileBytes.add(nextByte);

				}

				int[] fileBytes = new int[readedFileBytes.size()];

				for (int i = 0; i < readedFileBytes.size(); i++) {
						fileBytes[i] = readedFileBytes.get(i);
				}


				int levelsCount = fileBytes[0];
				int[] heights = new int[levelsCount];
				int[] widths = new int[levelsCount];

				byte[][] levelBytes = new byte[levelsCount][];

				levels = new Level[levelsCount];

				byte height, width;
				int n = 0;

				for (int i = 1; i < fileBytes.length; i++) {

						width = (byte) fileBytes[i];
						i = i + 1;
						height = (byte) fileBytes[i];

						levelBytes[n] = new byte[height * width];
						heights[n] = height;
						widths[n] = width;

						for (int j = 0; j < height * width;) {

								i = i + 1;

								levelBytes[n][j] = (byte) (fileBytes[i] >> 4);
								j += 1;
								if (j == height * width) {
										break;
								}
								levelBytes[n][j] = (byte) (fileBytes[i] & 15);
								j += 1;

						}

						n = n + 1;

				}

				for (int i = 0; i < levelsCount; i++) {

						levels[i] = new Level(widths[i], heights[i], levelBytes[i]);

				}

		}

		/**
		 * Получить уровень по его номеру.
		 *
		 * @param num Номер уровня
		 * @return Уровень
		 */
		public static Level getLevel(int num) {

				return (Level) levels[num].clone();

		}

		/**
		 * Общее количество уровней.
		 *
		 * @return Количество уровней
		 */
		public static int levelAmount() {
				return levels.length;
		}

}
